﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using Moonlite.ExtensionApi.XimlInterfaces;

namespace Moonlite.Platform.Ximl
{
    public class BarItemNodeDataProvider : INodeDataProvider
    {
        bool INodeDataProvider.ParseXimlNode(ref IXimlNode node, out DescriptorBase descriptor)
        {
            descriptor = null;
            if (node.Name == "BarItem")
            {
                bool reference = node["guid"].StartsWith("{") && node["guid"].EndsWith("}");
                if (string.IsNullOrEmpty(node["guid"]))
                {
                    throw new XimlInvalidElementException("The BarItem Ximl element must have attribute guid.");
                }
                if (!reference && string.IsNullOrEmpty(node["text"]))
                {
                    throw new XimlInvalidElementException("The BarItem Ximl element must have attribute text.");
                }
                DescriptorBase parent = (DescriptorBase)node.Parent.Tag;
                if (!reference)
                {
                    node["guid"] = ResourceManager.ConvertReferenceToString(node["guid"]);
                    descriptor = new BarItemDescriptor(node, parent, node["guid"]);
                    node["text"] = ResourceManager.ConvertReferenceToString(node["text"]);
                    if (!string.IsNullOrEmpty(node["index"]))
                    {
                        ((BarItemDescriptor)descriptor).Index = int.Parse(node["index"]);
                    }
                    if (!string.IsNullOrEmpty(node["separator"]))
                    {
                        ((BarItemDescriptor)descriptor).Separator = bool.Parse(node["separator"]);
                    }
                    ((BarItemDescriptor)descriptor).Text = node["text"];
                    if (!XimlTree.Instance.IsNativeElement(node["guid"]))
                    {
                        XimlTree.Instance.Descriptors.Add(node["guid"], descriptor);
                    }
                    else
                    {
                        return false;
                    }
                    if (XimlTree.Instance.CurrentAssembly == null)
                    {
                        throw new NoAssemblyContextException("No valid assembly context found.");
                    }
                    if (!string.IsNullOrEmpty(node["image"]))
                    {
                        if (node["image"].StartsWith("$"))
                        {
                            node["image"] = node["image"].TrimStart('$');
                            if (!ResourceManager.ResourceExists(node["image"], ResourceTypes.ImageType))
                            {
                                throw new InvalidOperationException("Image resource does not exist.");
                            }
                            else
                            {
                                node["image"] = ResourceManager.GetStringFromResourceString(node["text"]);
                            }
                            object image = null;
                            if (!XimlTree.Instance.Resources.TryGetValue(node["image"], out image))
                            {
                                throw new ResourceNotFoundException("Image resource at " + node["image"] + " not found.");
                            }
                            ((BarItemDescriptor)descriptor).Icon = (Image)image;
                        }
                        else
                        {
                            Stream imageStream = ResourceManager.GetStream(node["image"], XimlTree.Instance.CurrentAssembly);
                            ((BarItemDescriptor)descriptor).Icon = Image.FromStream(imageStream);
                        }
                    }
                    if (!string.IsNullOrEmpty(node["commandClass"]))
                    {
                        Type classType = XimlTree.Instance.CurrentAssembly.GetType(node["commandClass"]);
                        if (classType == null)
                        {
                            throw new TypeNotFoundException("Type at " + node["commandClass"] + " not found.");
                        }
                        ((BarItemDescriptor)descriptor).CommandType = classType;
                    }
                }
                else
                {
                    node["guid"] = node["guid"].Trim(new char[] { '{', '}' });
                    node["guid"] = ResourceManager.ConvertReferenceToString(node["guid"]);
                    descriptor = XimlTree.Instance.GetDescriptorFromGuid(node["guid"]);
                    if (parent != null)
                    {
                        parent.Children.Add(descriptor);
                    }
                    if (descriptor == null)
                    {
                        throw new InvalidOperationException("Could not find object with Guid " + node["guid"]);
                    }
                    if (descriptor is BarItemDescriptor)
                    {
                        node = descriptor.Node;
                    }
                    else
                    {
                        throw new InvalidOperationException("Object that is identified by the Guid " + node["guid"] + " is not of type BarItem.");
                    }
                }
                return true;
            }
            return false;
        }
    }
}
